package cc.xsubj.engine;

import cc.xsubj.engine.entity.Entity;

import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Vector2f;

/**
 * 
 * for now let's just assume that the camera covers the whole screen, starting
 * at 0,0 so no clipping area necessary
 * 
 */
public class MarteCamera extends Camera {

	Vector2f maxSpeed = null;
	int horBorderPixel = 0;
	int vertBorderPixel = 0;
	public MarteCamera(World world, Entity toFollow, int width, int height) {
		this(world, toFollow, width, height, -1, -1, null);
	}

	public MarteCamera(World world, Entity toFollow, int width, int height,
			int horBorderPixel, int vertBorderPixel, Vector2f maxSpeed) {
		super(world, toFollow, width, height);
		this.horBorderPixel = horBorderPixel;
		this.vertBorderPixel = vertBorderPixel;
		this.maxSpeed = maxSpeed;
		if (toFollow != null) {
			// on startup position camera that toFollow is in the center of the
			// screen
			this.cameraX = follow.x - (this.renderWidth / 2);
			this.cameraY = follow.y - (this.renderHeight / 2);
		}
		this.world = world;
		this.viewport = new Rectangle(cameraX - horBorderPixel, cameraY
				- vertBorderPixel, renderWidth + horBorderPixel, renderHeight
				+ vertBorderPixel);
		this.bounds = new Rectangle(cameraX + horBorderPixel / 2 - follow.speed.x,
                cameraY + vertBorderPixel / 2, renderWidth - horBorderPixel
                + follow.speed.x, renderHeight - vertBorderPixel);
		setCamera();
	}

	protected void setCamera()
    {
        // position camera so that follow is on the center of the screen
    
        if (follow != null
                && !bounds.contains(follow.x + follow.width / 2, follow.y
                        + follow.height / 2)) {
            float targetCX = follow.x - (this.renderWidth / 2);
            float targetCY = follow.y - (this.renderHeight / 2);
            // now smoothly move camera on position cameraX, cameraY to position
            // targetCX, targetCY, using
            // maxSpeed
            if (maxSpeed != null) {
                if (Math.abs(targetCX - cameraX) > maxSpeed.x) {
                    if (targetCX > cameraX)
                        cameraX += maxSpeed.x * 2;
                    else
                        cameraX -= maxSpeed.x * 2;
                } else
                    cameraX = targetCX;
                if (Math.abs(targetCY - cameraY) > maxSpeed.y) {
                    if (targetCY > cameraY)
                        cameraY += maxSpeed.y * 2;
                    else
                        cameraY -= maxSpeed.y * 2;
                } else
                    cameraY = targetCY;
            } else {
                // move camera directly to new position
                cameraX = targetCX;
                cameraY = targetCY;
            }
            // recalculate worldX and worldY based on translateX and translateY
        }
        // Log.debug("setCamera(): cameraX = " + cameraX + ", cameraY = " +
        // cameraY + ", follow.x = " + follow.x + ", follow.y = " + follow.y);
        // do some border checking. we want to stay inside the world with our
        // container
        if (cameraX < 0)
            cameraX = 0;
        if (cameraX + renderWidth > world.width)
            cameraX = world.width - renderWidth + 1;
        if (cameraY < 0)
            cameraY = 0;
        if (cameraY + renderHeight > world.height)
            cameraY = world.height - renderHeight + 1;
        // Log.debug("setCamera2(): cameraX = " + cameraX + ", cameraY = " +
        // cameraY + ", follow.x = " + follow.x + ", follow.y = " + follow.y);
        // also calculate rendering rect to improve speed in contains() method
        // later on for rendering
        viewport.setBounds(cameraX - horBorderPixel, cameraY
                - vertBorderPixel, renderWidth + horBorderPixel, renderHeight
                + vertBorderPixel);
        bounds.setBounds(cameraX + horBorderPixel / 2 - follow.speed.x,
                cameraY + vertBorderPixel / 2, renderWidth - horBorderPixel
                        + follow.speed.x, renderHeight - vertBorderPixel);
    }

}
